﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using ZBJF.Warranty.Common.Enums;
using ZBJF.Warranty.Common.Enums.Certificate;
using ZBJF.Warranty.Common.Enums.Data;
using ZBJF.Warranty.Common.Enums.InsuranceOrder;
using ZBJF.Warranty.Common.Enums.InsuranceOrder.Data;

namespace ZBJF.Warranty.Common.Common
{
    public static class CommonMethod
    {

        public static string GetRedirectUrl(RedirectType redirectType, string msg, string redirectUrl = null)
        {
            return string.Format("/Common/Redirect?RedirectType={0}&Msg={1}&RedirectUrl={2}", redirectType, msg,
                string.IsNullOrEmpty(redirectUrl) ? "/Search" : redirectUrl);
        }
        private static readonly string EncryptKey = "Oyea";    //定义密钥  

        #region 加密字符串
        /// <summary> /// 加密字符串   
        /// </summary>  
        /// <param name="str">要加密的字符串</param>  
        /// <returns>加密后的字符串</returns>  
        public static string JiaMi(string str)
        {
            DESCryptoServiceProvider descsp = new DESCryptoServiceProvider();   //实例化加/解密类对象   

            byte[] key = Encoding.Unicode.GetBytes(EncryptKey); //定义字节数组，用来存储密钥    

            byte[] data = Encoding.Unicode.GetBytes(str);//定义字节数组，用来存储要加密的字符串  

            MemoryStream mStream = new MemoryStream(); //实例化内存流对象      

            //使用内存流实例化加密流对象   
            CryptoStream cStream = new CryptoStream(mStream, descsp.CreateEncryptor(key, key), CryptoStreamMode.Write);

            cStream.Write(data, 0, data.Length);  //向加密流中写入数据      

            cStream.FlushFinalBlock();              //释放加密流      

            return Convert.ToBase64String(mStream.ToArray());//返回加密后的字符串  
        }
        #endregion

        #region 解密字符串
        /// <summary>  
        /// 解密字符串   
        /// </summary>  
        /// <param name="str">要解密的字符串</param>  
        /// <returns>解密后的字符串</returns>  
        public static string JieMi(string str)
        {
            DESCryptoServiceProvider descsp = new DESCryptoServiceProvider();   //实例化加/解密类对象    

            byte[] key = Encoding.Unicode.GetBytes(EncryptKey); //定义字节数组，用来存储密钥    

            byte[] data = Convert.FromBase64String(str);//定义字节数组，用来存储要解密的字符串  

            MemoryStream mStream = new MemoryStream(); //实例化内存流对象      

            //使用内存流实例化解密流对象       
            CryptoStream cStream = new CryptoStream(mStream, descsp.CreateDecryptor(key, key), CryptoStreamMode.Write);

            cStream.Write(data, 0, data.Length);      //向解密流中写入数据     

            cStream.FlushFinalBlock();               //释放解密流      

            return Encoding.Unicode.GetString(mStream.ToArray());       //返回解密后的字符串  
        }
        #endregion


        #region 记录文本日志
        public static void WriteLogs(string strLogTxt)
        {
            try
            {
                string strTmpPath = System.Threading.Thread.GetDomain().BaseDirectory.ToString().Trim() + "Logs\\";

                WriteLogs(strTmpPath, strLogTxt);
            }
            catch
            {
            }
        }

        private static void WriteLogs(string strPath, string strLogTxt)
        {
            if (!System.IO.Directory.Exists(strPath))
            {
                System.IO.Directory.CreateDirectory(strPath);
            }
            string logFilePath = strPath + "\\" + DateTime.Now.ToString("yyyy");
            if (!System.IO.Directory.Exists(logFilePath))
            {
                System.IO.Directory.CreateDirectory(logFilePath);
            }
            logFilePath = logFilePath + "\\" + DateTime.Now.ToString("MM");
            if (!System.IO.Directory.Exists(logFilePath))
            {
                System.IO.Directory.CreateDirectory(logFilePath);
            }
            logFilePath = logFilePath + "\\" + DateTime.Now.ToString("dd") + ".txt";
            string logText = "[" + DateTime.Now + "]\r\n"
                + strLogTxt + "\r\n-------------------------------------------------------------\r\n\r\n";
            byte[] logBytes = Encoding.UTF8.GetBytes(logText);
            System.IO.FileStream file = System.IO.File.Open(logFilePath, System.IO.FileMode.OpenOrCreate);
            file.Seek(0, System.IO.SeekOrigin.End);
            file.Write(logBytes, 0, logBytes.Length);
            file.Close();
        }

        #endregion

        #region 流水号
        public static string GetTimeStamp(int fromYear = 2016, bool isMilliSenconds = true)
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(fromYear, 1, 1, 0, 0, 0, 0);
            if (isMilliSenconds)
                return Convert.ToInt64(ts.TotalMilliseconds).ToString();
            return Convert.ToInt64(ts.TotalSeconds).ToString();
        }

        public static DateTime TimestampToDateTime(this DateTime dt, long timestamp)
        {
            var start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            return start.AddSeconds(timestamp);
        }

        public static string GetNewOrderNo()
        {
            return DateTime.Now.ToString("yyMMddHHmmssfff");
        }

        #endregion

        #region List2DataTable
        public static DataTable ListToDataTable<T>(List<T> data)
        {
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
            DataTable dt = new DataTable();
            for (int i = 0; i < properties.Count; i++)
            {
                PropertyDescriptor property = properties[i];
                dt.Columns.Add(property.Name, property.PropertyType);
            }
            object[] values = new object[properties.Count];
            foreach (T item in data)
            {
                for (int i = 0; i < values.Length; i++)
                {
                    values[i] = properties[i].GetValue(item);
                }
                dt.Rows.Add(values);
            }
            return dt;
        }
        #endregion

        /// <summary>
        /// 分割字符串
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string[] SplitStringArray(string str)
        {
            if (str == null)
                return null;
            return str.Split(new[] { ',', '，', ';', '|' }, StringSplitOptions.RemoveEmptyEntries);
        }

        public static bool IsInString(string arrStr, string itemStr)
        {
            var arr = SplitStringArray(arrStr);
            return arr != null && arr.Any(item => String.Equals(item, itemStr, StringComparison.CurrentCultureIgnoreCase));
        }
        public static string GetIP()
        {
            string ip = String.Empty;
            if (!String.IsNullOrEmpty(HttpContext.Current.Request.ServerVariables["HTTP_VIA"]))
                ip = Convert.ToString(HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]);
            if (String.IsNullOrEmpty(ip))
                ip = Convert.ToString(HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]);
            return ip;
        }

        /// <summary>
        /// 获得指定数量的html空格
        /// </summary>
        /// <returns></returns>
        public static string GetHtmlBlankSpace(int count)
        {
            StringBuilder result = new StringBuilder();
            for (int i = 0; i < count; i++)
                result.Append("&nbsp;");
            return result.ToString();
        }
        /// <summary>
        /// 将数字转为TimeSpan类型
        /// </summary>
        /// <param name="second"></param>
        /// <returns></returns>
        public static string TimeSencondToString(int second)
        {
            TimeSpan ts = new TimeSpan(0, 0, Convert.ToInt32(second));
            return TimeSpanToString(ts);
        }
        /// <summary>
        /// 将TimeSpan转换成×天×小时×分钟
        /// </summary>
        /// <param name="ts"></param>
        /// <returns></returns>
        public static string TimeSpanToString(TimeSpan ts)
        {
            var result = string.Empty;
            if (ts.Days > 0) result += ts.Days + " 天 ";
            if (ts.Hours > 0) result += ts.Hours + " 小时 ";
            if (ts.Minutes > 0) result += ts.Minutes + " 分钟 ";

            if (ts.Days == 0 && ts.Hours == 0 && ts.Minutes == 0)
                result += ts.Seconds + " 秒";

            return result;
        }

        public static byte[] GetImgFileData(string filePath)
        {
            using (FileStream stream = File.OpenRead(filePath))
            {
                byte[] fileBytes = new byte[stream.Length];

                stream.Read(fileBytes, 0, fileBytes.Length);
                stream.Close();
                return fileBytes;
            }
        }

        public static string SaveBase64Image(string strPath, string base64String)
        {
            string filePath = string.Empty;
            string returnPath = string.Empty;
            try
            {
                byte[] arr2 = Convert.FromBase64String(base64String);
                using (MemoryStream ms2 = new MemoryStream(arr2))
                {
                    System.Drawing.Bitmap bmp2 = new System.Drawing.Bitmap(ms2);
                    ////只有把当前的图像复制一份，然后把旧的Dispose掉，那个文件就不被锁住了，
                    ////这样就可以放心覆盖原始文件，否则GDI+一般性错误(A generic error occurred in GDI+)
                    string strTmpPath = strPath + //AppDomain.CurrentDomain.BaseDirectory +
                                        "\\UploadFile\\File\\";
                    if (!Directory.Exists(strTmpPath))
                    {
                        Directory.CreateDirectory(strTmpPath);
                    }
                    filePath = strTmpPath + "\\" + DateTime.Now.ToString("yyyy");
                    if (!Directory.Exists(filePath))
                    {
                        Directory.CreateDirectory(filePath);
                    }
                    filePath = filePath + "\\" + DateTime.Now.ToString("MM");
                    if (!Directory.Exists(filePath))
                    {
                        Directory.CreateDirectory(filePath);
                    }
                    filePath = filePath + "\\" + DateTime.Now.ToString("dd");
                    if (!Directory.Exists(filePath))
                    {
                        Directory.CreateDirectory(filePath);
                    }
                    string fileNme = DateTime.Now.ToString("yyyyMMddhhMMss") + ".jpg";

                    returnPath = "/UploadFile/File/" + DateTime.Now.ToString("yyyy/MM/dd", DateTimeFormatInfo.InvariantInfo) + "/" + fileNme;
                    filePath = filePath + "\\" + fileNme;
                    bmp2.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg);
                    bmp2.Dispose();
                }
            }
            catch (Exception ex)
            {
                CommonMethod.WriteLogs("SaveBase64Image Error:" + ex.Message + ex.StackTrace);
            }
            return returnPath;
        }

        #region  根据传入的名称返回对应的（UserCertificateType）枚举的值  static UserCertificateType GetCertificateType(string certificateType)
        /// <summary>
        /// 根据传入的名称返回对应的（UserCertificateType）枚举的值
        /// </summary>
        /// <param name="certificateType">传入的名称</param>
        /// <returns></returns>
        public static UserCertificateType GetCertificateType(string certificateType)
        {
            switch (certificateType)
            {
                case "身份证":
                    return UserCertificateType.IdentityCard;
                case "护照":
                    return UserCertificateType.Passport;
                case "军官证":
                    return UserCertificateType.CertificateOfOfficers;
                case "港澳回乡证或台胞证":
                    return UserCertificateType.HKAndMacaoHomeCardOrTaiwanCard;
                case "其他":
                    return UserCertificateType.OtherCard;
                default:
                    return UserCertificateType.IdentityCard;
            }
        }
        #endregion

        #region  根据传入的名称返回对应的（InsuranceOrderDeviceType）枚举的值  static InsuranceOrderDeviceType GetOrderDeviceType(string orderDerviceType)
        /// <summary>
        ///  根据传入的名称返回对应的（InsuranceOrderDeviceType）枚举的值
        /// </summary>
        /// <param name="orderDerviceType">传入的名称</param>
        /// <returns></returns>
        public static InsuranceOrderDeviceType GetOrderDeviceType(string orderDerviceType)
        {
            switch (orderDerviceType)
            {
                case "新机":
                    return InsuranceOrderDeviceType.NewMachine;
                case "在用机":
                    return InsuranceOrderDeviceType.InUseMachine;
                default:
                    return InsuranceOrderDeviceType.NewMachine;
            }
        }
        #endregion

        #region  替换 \R\N 清楚收尾空格   static string GetTrimStr(string str)
        /// <summary>
        /// 替换 \R\N 清楚收尾空格
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string GetTrimStr(string str)
        {
            str = str.Replace("\\r\\n", string.Empty).Replace("'", string.Empty).Trim();
            return str.Trim();
        }
        #endregion

        #region 根据身份证获取性别 M：男  F：女  static string GetSexByIndentityNo(string indentityNo)
        /// <summary>
        /// 根据身份证获取性别 M：男  F：女
        /// </summary>
        /// <param name="indentityNo"></param>
        /// <returns></returns>
        public static string GetSexByIndentityNo(string indentityNo)
        {
            var birthday = string.Empty;
            var sexTemp = string.Empty;
            var sex = string.Empty;
            if (indentityNo.Length == 18)
            {
                birthday = indentityNo.Substring(6, 4) + "-" + indentityNo.Substring(10, 2) + "-" + indentityNo.Substring(12, 2);
                sexTemp = indentityNo.Substring(14, 3);
            }
            if (indentityNo.Length == 15)
            {
                birthday = "19" + indentityNo.Substring(6, 2) + "-" + indentityNo.Substring(8, 2) + "-" + indentityNo.Substring(10, 2);
                sexTemp = indentityNo.Substring(12, 3);
            }
            if (int.Parse(sexTemp) % 2 == 0)
            {
                sex = "F";//"女";
            }
            else
            {
                sex = "M"; //"男";
            }
            return sex;
        }
        #endregion

        #region 根据身份证获取生日   static string GetBirthdayByIndentityNo(string indentityNo)
        /// <summary>
        /// 根据身份证获取生日
        /// </summary>
        /// <param name="indentityNo"></param>
        /// <returns></returns>
        public static string GetBirthdayByIndentityNo(string indentityNo)
        {
            var birthday = string.Empty;
            var sexTemp = string.Empty;
            var sex = string.Empty;
            if (indentityNo.Length == 18)
            {
                birthday = indentityNo.Substring(6, 4) + "-" + indentityNo.Substring(10, 2) + "-" + indentityNo.Substring(12, 2);
                sexTemp = indentityNo.Substring(14, 3);
            }
            if (indentityNo.Length == 15)
            {
                birthday = "19" + indentityNo.Substring(6, 2) + "-" + indentityNo.Substring(8, 2) + "-" + indentityNo.Substring(10, 2);
                sexTemp = indentityNo.Substring(12, 3);
            }
            sex = int.Parse(sexTemp) % 2 == 0 ? "F" : "M";
            return birthday;
        }
        #endregion

        #region  判断是否是微信内置的浏览器  static bool IsRequestFormWeiXin(string userAgent)
        /// <summary>
        /// 判断是否是微信内置的浏览器
        /// </summary>
        /// <param name="userAgent"></param>
        /// <returns></returns>
        public static bool IsRequestFormWeiXin(string userAgent)
        {
            return userAgent.ToLower().Contains("micromessenger");
        }
        #endregion

        #region 将时间戳转换成（DateTime）时间    static DateTime ConvertToDateTime(string timeStr)
        /// <summary>
        /// 将时间戳转换成（DateTime）时间
        /// </summary>
        /// <param name="timeStr">时间戳</param>
        /// <returns></returns>
        public static DateTime ConvertToDateTime(string timeStr)
        {
            //20180103000000
            if (timeStr.Length >= 14)
                return new DateTime(int.Parse(timeStr.Substring(0, 4)), int.Parse(timeStr.Substring(4, 2)),
                    int.Parse(timeStr.Substring(6, 2)), int.Parse(timeStr.Substring(8, 2)),
                    int.Parse(timeStr.Substring(10, 2)), int.Parse(timeStr.Substring(12, 2)));
            return new DateTime();
        }
        #endregion

        #region 获取前时间戳(秒) + static long GetTimestamp(DateTime dt)
        /// <summary>
        /// 获取时间戳(秒)
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static long GetTimeStamp(DateTime dt)
        {
            TimeSpan ts = dt.ToUniversalTime() - new DateTime(1970, 1, 1);
            return Convert.ToInt64(ts.TotalSeconds);    //精确到毫秒
        }

        #endregion

        #region 得到服务开始时间 + DateTime GetServiceStartTime(DateTime nowTime, int waitDays)
        /// <summary>
        /// 得到服务结束时间
        /// </summary>
        /// <param name="nowTime">当前时间</param>
        /// <param name="waitDays">生效等待期</param>
        /// <returns></returns>
        public static DateTime GetServiceStartTime(DateTime nowTime, int waitDays)
        {
            return Convert.ToDateTime(nowTime.AddDays(waitDays).ToString("yyyy-MM-dd 00:00:00"));
        }
        #endregion

        #region 得到服务结束时间  static DateTime GetServiceEndTime(DateTime startTime, int policyPeriod, byte plicyPeriodUnit)
        /// <summary>
        /// 得到服务结束时间
        /// </summary>
        /// <param name="startTime">保险开始时间</param>
        /// <param name="policyPeriod">保险期限</param>
        /// <param name="plicyPeriodUnit">时间单位</param>
        /// <returns></returns>
        public static DateTime GetServiceEndTime(DateTime startTime, short? policyPeriodYear, short? policyPeriodMonth, short?  policyPeriodDay)
        {
           
            if (policyPeriodYear.HasValue)
            {
                startTime.AddYears(policyPeriodYear.Value);
            }
            else if (policyPeriodMonth.HasValue)
            {
                startTime.AddMonths(policyPeriodMonth.Value);
            }
            else if(policyPeriodDay.HasValue)
            {
                startTime.AddDays(policyPeriodDay.Value);
            }
            return startTime;
        }
        #endregion

        #region 生成编码 + string GenerateCode(string head, string id, int length = 6)
        /// <summary>
        /// 生成编码
        /// </summary>
        /// <param name="head">编码头</param>
        /// <param name="id">唯一ID</param>
        /// <param name="length">编码的后面部分的长度（id前面补0的方式）</param>
        /// <returns></returns>
        public static string GenerateCode(string head, string id, int length = 6)
        {
            if (string.IsNullOrEmpty(id))
                throw new Exception("唯一ID参数不能为空");
            for (int i = 0, j = length - id.Length; i < j; i++)
            {
                id = "0" + id;
            }
            return head + id;
        }
        #endregion
    }
}
